package br.com.livro.javapersistence.heranca;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;

import br.com.livro.javapersistence.commons.Execucao;
import br.com.livro.javapersistence.commons.model.CommonField;
import br.com.livro.javapersistence.commons.util.ExecucaoHibernate;
import br.com.livro.javapersistence.commons.util.HibernateUtil;
import br.com.livro.javapersistence.heranca.model.Pessoa;
import br.com.livro.javapersistence.heranca.model.PessoaFisica;
import br.com.livro.javapersistence.heranca.model.PessoaJuridica;
import br.com.livro.javapersistence.heranca.model.Solicitacao;
import br.com.livro.javapersistence.heranca.model.SolicitacaoCliente;
import br.com.livro.javapersistence.heranca.model.SolicitacaoContrato;

public class CriacaoHierarquia implements Execucao {

	private Session session;

	public static void main(String[] args) throws ParseException {
		CriacaoHierarquia criacaoHierarquia = new CriacaoHierarquia();
		criacaoHierarquia.execute(HibernateUtil.getSessionFactoryAnnotation(true, criacaoHierarquia.getAnnotatedClasses()).openSession());
	}

	/**
	 * @throws ParseException
	 * 
	 */
	public void execute(Session session) {
		try {
			this.session = session;
			this.criarConjuntoDeInsercoes();
			//this.excluirSomenteContrato();
			this.incluirVariosContratosParaUmaPessoa();
			this.listarPessoas();
		} catch (ParseException e) {
			e.printStackTrace();
		}
		// this.excluirPessoaCascateada();
	}

	@SuppressWarnings("unchecked")
	private void listarPessoas() {
		List<PessoaFisica> list = session.createCriteria(PessoaFisica.class).list();
		for (PessoaFisica pessoaFisica : list) {
			System.out.println("pessoa: " + pessoaFisica.getNome() + " sol: " + pessoaFisica.getSolicitacoes().size() );
		}
	}

	/**
	 * @throws ParseException
	 */
	private void criarConjuntoDeInsercoes() throws ParseException {
		Date dataNascimento = new SimpleDateFormat("dd/MM/yyyy").parse("09/03/1987");
		PessoaFisica pessFisicaAtiva = new PessoaFisica(new CommonField(true), 1111l, "25869745698", "416145115", "Leo Jose da costa", dataNascimento);
		PessoaJuridica pessJuridica = new PessoaJuridica(new CommonField(true), 2222l, "09201758000188", "Lelo desenvolvimento de sistemas Ltda", "Lelo dev");
		PessoaFisica pessFisicaInativa = new PessoaFisica(new CommonField(false), 3333l, "32145874596", "416145115", "Mauricio matar", dataNascimento);
		Transaction beginTransaction = session.beginTransaction();
		{
			session.persist(this.criarSolicitacao(pessFisicaAtiva));
			session.persist(this.criarSolicitacao(pessFisicaInativa));
			session.persist(this.criarSolicitacao(pessJuridica));
		}
		beginTransaction.commit();
	}

	/**
	 * @throws HibernateException
	 * @throws ParseException
	 */
	private void incluirVariosContratosParaUmaPessoa() throws HibernateException, ParseException {
		Transaction transaction = session.beginTransaction();
		Pessoa pessFisica = (PessoaFisica) session.createCriteria(PessoaFisica.class).add(Restrictions.eq("pessoaId", 1l)).uniqueResult();
		int total = 0;
		while (total < 10) {
			session.persist(this.criarSolicitacao((PessoaFisica) pessFisica));
			total++;
		}
		session.evict(pessFisica);
		transaction.commit();
		System.out.println(pessFisica);
	}

	/**
	 * 
	 */
	@SuppressWarnings("unused")
	private void excluirSomenteContrato() {
		Transaction transaction = session.beginTransaction();
		SolicitacaoContrato solicitacaoContrato = (SolicitacaoContrato) session.load(SolicitacaoContrato.class, 2l);
		session.delete(solicitacaoContrato);
		transaction.commit();
	}

	/**
	 * 
	 */
	@SuppressWarnings("unused")
	private void excluirPessoaCascateada() {
		Transaction transaction = session.beginTransaction();
		Pessoa fisica = (PessoaFisica) session.createCriteria(PessoaFisica.class).add(Restrictions.eq("userId", 1111l)).uniqueResult();
		session.delete(fisica);
		transaction.commit();
	}

	/**
	 * @param pessFisica
	 * @return
	 */
	private Solicitacao criarSolicitacao(PessoaFisica pessFisica) {
		if (pessFisica == null)
			throw new IllegalArgumentException("Pessoa can not be null");

		SolicitacaoCliente solicitacaoCliente = new SolicitacaoCliente(new CommonField(true), 15, pessFisica, 150.00, 3.0, true);
		return solicitacaoCliente;
	}

	/**
	 * @param pessJuridica
	 * @return
	 * @throws ParseException
	 */
	private Solicitacao criarSolicitacao(PessoaJuridica pessJuridica) throws ParseException {
		if (pessJuridica == null)
			throw new IllegalArgumentException("Pessoa can not be null");

		Date dataVencimento = new SimpleDateFormat("dd/MM/yyyy").parse("09/03/2011");
		SolicitacaoContrato soliContrato = new SolicitacaoContrato(new CommonField(true), 15, pessJuridica, 150.00, 3.0, dataVencimento);
		pessJuridica.addSolicitacao(soliContrato);
		return soliContrato;
	}

	@Override
	public ExecucaoHibernate getAnnotatedClasses() {
		return ExecucaoHibernate.HIERARQUIA;
	}
}
